/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package comunicacao;

import gui.Telas;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.Connector;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.UUID;
import java.io.DataInputStream;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
import util.*;

/**
 *
 * @author Pablo Viana
 */
public class ComunicacaoRemota implements Comunicacao, DiscoveryListener {

    private String serviceUrl;
    private DiscoveryAgent discoveryAgent;
    private StreamConnection conn;
    private OutputStream output;
    private InputStream input;

    private static final UUID[] uuids = new UUID[] { Constantes.DOMINO_UUID };
    private Vector services; // vector of the devices found by the inquiry requested
    private Telas telas;
    
    // METODOS IMPLEMENTADOS DE DISCOVERYLISTENNER /////////////////////////////
    public ComunicacaoRemota(Telas telas) {
        try {
            this.telas = telas;
            this.services = new Vector();
            LocalDevice localDevice = LocalDevice.getLocalDevice();
            discoveryAgent = localDevice.getDiscoveryAgent();
            discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
            this.telas.setTitleTelaServidores("Servidores Procurando...");
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
        System.out.println("ComunicacaoRemota.deviceDiscovered();");
        // TODO Auto-generated method stub
        try {
            // Procurando por serviços
            discoveryAgent.searchServices(null, uuids, btDevice, this);            
        } catch (Exception e) {
            System.out.println("ComunicacaoRemota.deviceDiscovered(): Device Discovered Error: " + e);
        }
    }
    
    public void inquiryCompleted(int discType) {
        System.out.println("ComunicacaoRemota.inquiryCompleted();");
    }

    public void servicesDiscovered(int transdId, ServiceRecord[] servRecord) {
        System.out.println("ComunicacaoRemota.servicesDiscovered();");
        RemoteDevice device = servRecord[0].getHostDevice();
        this.telas.atualizarTelaServidores(device.getBluetoothAddress());
        this.services.addElement(servRecord[0]);        
    }

    public void serviceSearchCompleted(int trasnId, int responseCode) {
        if (responseCode == DiscoveryListener.SERVICE_SEARCH_COMPLETED) {
            this.telas.setTitleTelaServidores("Servidores Encontrados:");
            System.out.println("ComunicacaoRemota.serviceSearchCompleted(): SERVICE_SEARCH_COMPLETED\n");
            System.out.println("ComunicacaoRemota.serviceSearchCompleted(): Service URL: " + serviceUrl);
        }
    }
    
    public void conectarNoServidor(int index) {
        ServiceRecord service = (ServiceRecord)services.elementAt(index);
        this.serviceUrl = service.getConnectionURL(0, false);    
    }

    // METODO DA COMUNICACAO REMOTA /////////////////////////////////////////////
    private boolean enviarPacote(Vector pacote) throws IOException {
        conn = (StreamConnection) Connector.open(this.serviceUrl);
        input = conn.openInputStream();
        output = conn.openOutputStream();
        output.write(Util.empacotarParametros(pacote));
        output.flush();
        System.out.println("ComunicacaoRemota.enviarPacote(): conexao estabelecida com sucesso");
        
        return (conn != null && input != null && output != null);
    }

    // METODOS IMPLEMENTADOS DE COMUNICACAO ////////////////////////////////////
    public DataInputStream retorneStatus(String nome, int partida, int rodada) throws IOException {        
        Vector pacote = new Vector();
        pacote.addElement(new Integer(Constantes.PACOTE_STATUS));
        pacote.addElement(nome);
        pacote.addElement(new Integer(partida));
        pacote.addElement(new Integer(rodada));
        this.enviarPacote(pacote);
        
        return new DataInputStream(input);
    }

    public void entrarNoJogo(String nome) throws IOException  {
        Vector pacote = new Vector();
        pacote.addElement(new Integer(Constantes.PACOTE_CONECTAR));
        pacote.addElement(nome);
        this.enviarPacote(pacote);        
    }

    public void jogar(Vector dados) throws IOException {
        Vector pacote = new Vector();
        pacote.addElement(new Integer(Constantes.PACOTE_JOGAR));
        for(Enumeration e = dados.elements(); e.hasMoreElements();) {
            pacote.addElement(e.nextElement());
        }
        this.enviarPacote(pacote);
    }
   
    
}
